AnsibleでCentOS6のeasy_installが失敗する時はcommandモジュールを使う
渡辺です。 CentOS6とAnsibleでちょっとハマったので共有します。
AmazonLinux以外でAWS CLIをインストールする場合、pipでインストールするのが基本です。 pipはeasy_installでインストールできるので、コマンドは次のようになります。
$ sudo easy_install pip $ sudo pip install awscli
これをAnsibleのタスクで定義すると次のようになります。
- name: pip installed easy_install: name: pip - name: awscli installed pip: name: awscli
ところが、CentOS6で、このPlaybookは失敗します。
TASK [aws/awscli : pip installed] ********************************************** fatal: [test.centos]: FAILED! => {"changed": false, "failed": true, "msg": "/usr/lib64/python2.6/distutils/dist.py:266: UserWarning: Unknown distribution option: 'python_requires'\n warnings.warn(msg)\nwarning: install_lib: 'build/lib' does not exist -- no Python modules to install\nTraceback (most recent call last):\n File \"/usr/bin/easy_install\", line 9, in <module>\n load_entry_point('distribute==0.6.10', 'console_scripts', 'easy_install')()\n File \"/usr/lib/python2.6/site-packages/setuptools/command/easy_install.py\", line 1715, in main\n with_ei_usage(lambda:\n File \"/usr/lib/python2.6/site-packages/setuptools/command/easy_install.py\", line 1696, in with_ei_usage\n return f()\n File \"/usr/lib/python2.6/site-packages/setuptools/command/easy_install.py\", line 1719, in <lambda>\n distclass=DistributionWithoutHelpCommands, **kw\n File \"/usr/lib64/python2.6/distutils/core.py\", line 152, in setup\n dist.run_commands()\n File \"/usr/lib64/python2.6/distutils/dist.py\", line 975, in run_commands\n self.run_command(cmd)\n File \"/usr/lib64/python2.6/distutils/dist.py\", line 995, in run_command\n cmd_obj.run()\n File \"/usr/lib/python2.6/site-packages/setuptools/command/easy_install.py\", line 236, in run\n self.easy_install(spec, not self.no_deps)\n File \"/usr/lib/python2.6/site-packages/setuptools/command/easy_install.py\", line 472, in easy_install\n return self.install_item(spec, dist.location, tmpdir, deps)\n File \"/usr/lib/python2.6/site-packages/setuptools/command/easy_install.py\", line 502, in install_item\n dists = self.install_eggs(spec, download, tmpdir)\n File \"/usr/lib/python2.6/site-packages/setuptools/command/easy_install.py\", line 681, in install_eggs\n return self.build_and_install(setup_script, setup_base)\n File \"/usr/lib/python2.6/site-packages/setuptools/command/easy_install.py\", line 958, in build_and_install\n self.run_setup(setup_script, setup_base, args)\n File \"/usr/lib/python2.6/site-packages/setuptools/command/easy_install.py\", line 947, in run_setup\n run_setup(setup_script, args)\n File \"/usr/lib/python2.6/site-packages/setuptools/sandbox.py\", line 29, in run_setup\n lambda: execfile(\n File \"/usr/lib/python2.6/site-packages/setuptools/sandbox.py\", line 70, in run\n return func()\n File \"/usr/lib/python2.6/site-packages/setuptools/sandbox.py\", line 31, in <lambda>\n {'__file__':setup_script, '__name__':'__main__'}\n File \"setup.py\", line 92, in <module>\n File \"/usr/lib64/python2.6/distutils/core.py\", line 152, in setup\n dist.run_commands()\n File \"/usr/lib64/python2.6/distutils/dist.py\", line 975, in run_commands\n self.run_command(cmd)\n File \"/usr/lib64/python2.6/distutils/dist.py\", line 995, in run_command\n cmd_obj.run()\n File \"/usr/lib/python2.6/site-packages/setuptools/command/bdist_egg.py\", line 236, in run\n dry_run=self.dry_run, mode=self.gen_header())\n File \"/usr/lib/python2.6/site-packages/setuptools/command/bdist_egg.py\", line 533, in make_zipfile\n visit(None, dirname, file)\n File \"/usr/lib/python2.6/site-packages/setuptools/command/bdist_egg.py\", line 514, in visit\n for name in names:\nTypeError: 'instancemethod' object is not iterable\n"}
一方、SSHログインし、サーバでコマンドを実行すれば問題無くインストール可能です。
python-setuptoolsのバグっぽい
エラーメッセージからググってみると、easy_installが含まれるpython-setuptoolsのバージョンで発生するバグのようです。 したがって、python-setuptoolsをアップデートすれば対応可能です。 とはいえ、python-setuptoolsはyum管理のパッケージです。 アップデートするには他のyumリポジトリからインストールしなければならず、別のリスクもでてきます。
commandモジュールで回避する
今回のケースではコマンド実行でもバグを回避できました。 そこで、commandモジュールを利用することにします。
- name: check pip command stat: path: /usr/bin/pip register: _pip_stat_result - name: install pip command: "easy_install pip" when: _pip_stat_result.stat.exists == false - name: awscli installed pip: name: awscli
statモジュールで存在チェックを行い、存在しない場合にcommandモジュールを実行という王道パターンです。
実行してみます。
TASK [aws/awscli : command] **************************************************** changed: [test.centos] => {"changed": true, "cmd": ["easy_install", "pip"], "delta": "0:00:02.123304", "end": "2017-02-21 09:04:11.301080", "rc": 0, "start": "2017-02-21 09:04:09.177776", "stderr": "/usr/lib64/python2.6/distutils/dist.py:266: UserWarning: Unknown distribution option: 'python_requires'\n warnings.warn(msg)", "stdout": "Searching for pip\nReading http://pypi.python.org/simple/pip/\nBest match: pip 9.0.1\nDownloading https://pypi.python.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz#md5=35f01da33009719497f01a4ba69d63c9\nProcessing pip-9.0.1.tar.gz\nRunning pip-9.0.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-XmjhRs/pip-9.0.1/egg-dist-tmp-Vlsxzv\nwarning: no previously-included files found matching '.coveragerc'\nwarning: no previously-included files found matching '.mailmap'\nwarning: no previously-included files found matching '.travis.yml'\nwarning: no previously-included files found matching '.landscape.yml'\nwarning: no previously-included files found matching 'pip/_vendor/Makefile'\nwarning: no previously-included files found matching 'tox.ini'\nwarning: no previously-included files found matching 'dev-requirements.txt'\nwarning: no previously-included files found matching 'appveyor.yml'\nno previously-included directories found matching '.github'\nno previously-included directories found matching '.travis'\nno previously-included directories found matching 'docs/_build'\nno previously-included directories found matching 'contrib'\nno previously-included directories found matching 'tasks'\nno previously-included directories found matching 'tests'\nAdding pip 9.0.1 to easy-install.pth file\nInstalling pip script to /usr/bin\nInstalling pip2.6 script to /usr/bin\nInstalling pip2 script to /usr/bin\n\nInstalled /usr/lib/python2.6/site-packages/pip-9.0.1-py2.6.egg\nProcessing dependencies for pip\nFinished processing dependencies for pip", "stdout_lines": ["Searching for pip", "Reading http://pypi.python.org/simple/pip/", "Best match: pip 9.0.1", "Downloading https://pypi.python.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz#md5=35f01da33009719497f01a4ba69d63c9", "Processing pip-9.0.1.tar.gz", "Running pip-9.0.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-XmjhRs/pip-9.0.1/egg-dist-tmp-Vlsxzv", "warning: no previously-included files found matching '.coveragerc'", "warning: no previously-included files found matching '.mailmap'", "warning: no previously-included files found matching '.travis.yml'", "warning: no previously-included files found matching '.landscape.yml'", "warning: no previously-included files found matching 'pip/_vendor/Makefile'", "warning: no previously-included files found matching 'tox.ini'", "warning: no previously-included files found matching 'dev-requirements.txt'", "warning: no previously-included files found matching 'appveyor.yml'", "no previously-included directories found matching '.github'", "no previously-included directories found matching '.travis'", "no previously-included directories found matching 'docs/_build'", "no previously-included directories found matching 'contrib'", "no previously-included directories found matching 'tasks'", "no previously-included directories found matching 'tests'", "Adding pip 9.0.1 to easy-install.pth file", "Installing pip script to /usr/bin", "Installing pip2.6 script to /usr/bin", "Installing pip2 script to /usr/bin", "", "Installed /usr/lib/python2.6/site-packages/pip-9.0.1-py2.6.egg", "Processing dependencies for pip", "Finished processing dependencies for pip"], "warnings": []}
無事、pipがインストールできました。